package v1

import (
	"bufio"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"os"
	"strconv"
	"sync"
	"time"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/lib/geetest"
	"zimuzu_cvn_web_api/lib/grpcClient"
	"zimuzu_cvn_web_api/model"
	"zimuzu_cvn_web_api/pkg/drive/redis"
	"zimuzu_cvn_web_api/pkg/e"
	. "zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/router/api"
	"zimuzu_cvn_web_api/service"
	"zimuzu_cvn_web_api/service/cron"
	"zimuzu_cvn_web_api/service/flows"
)

type TestAPI struct {
}

func (a TestAPI) Name() string {
	return "test API"
}

func (a TestAPI) Bind() {
	testAPI := config.C.Router.Group("/v1/")
	{
		testAPI.GET("study/test", Test)
		testAPI.GET("study/testReader", TestReader)
		testAPI.GET("study/testNode", TestNode)
		testAPI.GET("sleep", sleep)
		testAPI.GET("study/TestInterface", TestInterface)
		testAPI.GET("initSingleCvnAmount", InitSingleCvnAmount)
		testAPI.GET("initSingleUsdtAmount", InitSingleUsdtAmount)
		testAPI.GET("cvnAmountCheck", CvnAmountCheck)
		testAPI.GET("study/multiple/statistical", TestMultipleStatisticalStage)
		testAPI.GET("study/sync/pic", SyncPic)
		testAPI.GET("token", getToken)
	}
	test1API := config.C.Router.Group("/v2/test/")
	{
		test1API.GET("geet", geetInit)
		test1API.GET("login", testlogin)
		test1API.POST("validate", geetValidate)
		test1API.GET("checkdraw", CheckDraw)
		test1API.GET("readLog", readLog)
		test1API.GET("online", onlineTime)
	}
}

func getToken(c *gin.Context) {

	uid := int64(6367630)
	user, err := model.GetUserByUid(config.C.DB.DB, uid)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	token := service.CreateToken("app", user.Uid, user.Password, user.Nickname)
	errno.OK.Info = "获取测试环境Token成功"
	api.SendResponse(c, errno.OK, token)
	return
}

type testReaderParams struct {
	Hour int    `form:"hour"`
	Date string `form:"date"`
}

func SyncPic(c *gin.Context) {

	var wg sync.WaitGroup
	AgainNum, _ := strconv.Atoi(c.Query("nums"))
	wg.Add(AgainNum)
	for ik := 1; ik <= AgainNum; ik++ {
		go func(totalNum, ss int) {
			defer wg.Done()
			for ii := 0; ii < totalNum; ii++ {
				err := flows.DownTheFileFromX(c.Query("url"))
				if err != nil {
					e.Log("info", "取数据失败", err.Error())
				}
			}

		}(AgainNum, ik)
	}
	wg.Wait()
	e.Log("info", "线程组已全部完成")

	errno.OK.Info = "同步完成"
	api.SendResponse(c, errno.OK, nil)
}

func TestMultipleStatisticalStage(c *gin.Context) {

	redis.UnDelete(e.MultipleStatisticalForTag)
	cron.MultipleStatisticalStage()
	errno.OK.Info = "结算数据完成"
	api.SendResponse(c, errno.OK, nil)
}

func TestReader(c *gin.Context) {

	var params testReaderParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	e.Log("info", "传入的参数为：Date=", params.Date)
	e.Log("info", "传入的参数为：Hour=", params.Hour)
	err = flows.GetTwLastDayFlow(params.Hour, params.Date)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "读取成功"
	api.SendResponse(c, errno.OK, nil)
}

func onlineTime(c *gin.Context) {
	timeInt, _ := strconv.Atoi(c.Query("time"))
	oldStr := "{\"2020-04-23\":10}"
	res := service.UpdateOnlineTimeDB(oldStr, timeInt)
	api.SendResponse(c, errno.OK, res)
}

func readLog(c *gin.Context) {

	fileName := "./conf/cvnt_flow.log." + c.Query("title") + ".log"
	if file, err := os.Open(fileName); err != nil {
		api.SendResponse(c, errno.OK, "流量日志读取异常")
	} else {
		// 先获取到所以数据
		flowsNode, err := model.GetAllNodeIdForReport()
		if err != nil {
			api.SendResponse(c, errno.DbError, "处理失败")
		}
		var nodeMap map[string]model.ReportDB
		nodeMap = make(map[string]model.ReportDB)
		for _, node := range flowsNode {
			nodeMap[node.ReportId] = node
		}
		// 逐行读取数据
		var i, k, h, total int
		var flowJson model.TailWuFlowParams
		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			total++
			// 看看string解析是否能满足flows格式
			err := json.Unmarshal([]byte(scanner.Text()), &flowJson)
			if err != nil {
				i++
				e.Log("err", "数据格式异常：", err.Error())
				continue
			}
			if _, ok := nodeMap[flowJson.PId]; !ok {
				h++
				e.Log("err", "忽略更新：", flowJson.PId, " 不属于人人节点, 共有", h)
			}
			if nodeMap[flowJson.PId].NodeId <= 0 {
				h++
				e.Log("err", "忽略更新：", flowJson.PId, " 不属于人人节点, 共有", h)
			}
			err = flows.WriteTaiWuFlows(flowJson, nodeMap[flowJson.PId])
			if err != nil {
				i++
				e.Log("err", "更新失败：", err.Error())
			} else {
				k++
				e.Log("info", "数据正常解析共：", k, "次, 异常", i, "次")
			}
		}
		e.Log("info", "处理完成：共有节点:", total, ",忽略:", h, ", 处理完成:", k, ",失败:", i)
	}
	api.SendResponse(c, errno.OK, "流量日志读取完成")
}

func CheckDraw(c *gin.Context) {
	//service.CheckDraw()
	//api.SendResponse(c, errno.OK, "ok")
}

func sleep(c *gin.Context) {

	intD, _ := strconv.Atoi(c.Query("duration"))
	time.Sleep(time.Duration(intD) * time.Second)

	api.SendResponse(c, errno.OK, "Hello World 平滑重启")
}

func InitSingleCvnAmount(c *gin.Context) {
	valueStr := c.Query("uid")
	valueInt, _ := strconv.ParseInt(valueStr, 10, 64)
	service.InitSingleCvnAmount(valueInt)

	api.SendResponse(c, errno.OK, "Hello World ")
}

func InitSingleUsdtAmount(c *gin.Context) {
	valueStr := c.Query("uid")
	valueInt, _ := strconv.ParseInt(valueStr, 10, 64)
	service.InitSingleUsdtAmount(valueInt)

	api.SendResponse(c, errno.OK, "Hello World ")
}

func CvnAmountCheck(c *gin.Context) {
	valueStr := c.Query("uid")
	//校验账户签名
	request := map[string]string{
		"uid": valueStr,
	}
	var amountRes, logRes string
	amountCheckResponse, err := grpcClient.CvnAmountCheck(request)
	if err != nil {
		amountRes = err.Error()
	}
	if !amountCheckResponse.Ok {
		Log("err", errno.DbSignError)
		amountRes = "amount签名错误"
	}
	//校验流水签名
	logListCheckResponse, err := grpcClient.CvnLogListCheck(request)
	if err != nil {
		logRes = err.Error()
	}
	if logListCheckResponse.ErrNum > 0 {
		Log("err", errno.DbSignError)
		logRes = "log签名错误"
	}

	api.SendResponse(c, errno.OK, "Hello World "+amountRes+logRes)
}

func Test(c *gin.Context) {
	//rrapi.UpdatePassword("18672328625", 86, "A1sdfssdfs")
	// 参数校验
	var params model.FormatParams
	err := c.ShouldBindWith(&params, binding.Query)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	var logOut []string
	logOut = append(logOut, "2019-12:15 01:01:00", "测试第1个日志、")
	logOut = append(logOut, "测试第2个日志、")
	logOut = append(logOut, "测试第3个日志、")
	logOut = append(logOut, "测试第4个日志、")
	logOut = append(logOut, "测试第5个日志、")

	//redisKey := "111"
	//if redis.Exists(redisKey) {
	//	re, err := redis.Get(redisKey)
	//	if err != nil {
	//		e.LogParams("err", params, "redis get error")
	//	}
	//	e.LogParams("info", params, "redis exists key: ", re)
	//}

	LogParams("info", params, logOut)
	api.SendResponse(c, errno.OK, nil)
}

func TestInterface(c *gin.Context) {

	//shopService := shop.ShopGoodsService{GId: 1, Page: 1, PageSize: 10}
	//res, err := shopService.List()
	//if err != nil {
	//	api.SendResponse(c, errno.ParamsError, nil)
	//	return
	//}
	//errno.OK.Info = "获取信息成功"
	//api.SendResponse(c, errno.OK, res)
}

func TestNode(c *gin.Context) {

	typeInt, _ := strconv.Atoi(c.Query("type"))
	switch typeInt {
	case 1:
		flows.DailyBoard()
		errno.OK.Info = "今日看板数据更新成功"
		break
	case 2:
		cron.MultipleStatisticalProfit()
		errno.OK.Info = "今日结算统计成功"
		break
	case 3:
		cron.PaymentToProfitDetail("")
		errno.OK.Info = "今日用户收益统计成功"
		break
	}
	api.SendResponse(c, errno.OK, nil)
}

const page1 = `<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>gt-php-sdk-demo</title>
    <style>
        body {
            margin: 50px 0;
            text-align: center;
        }
        .inp {
            border: 1px solid gray;
            padding: 0 10px;
            width: 200px;
            height: 30px;
            font-size: 18px;
        }
        .btn {
            border: 1px solid gray;
            width: 100px;
            height: 30px;
            font-size: 18px;
            cursor: pointer;
        }
        #embed-captcha {
            width: 300px;
            margin: 0 auto;
        }
        .show {
            display: block;
        }
        .hide {
            display: none;
        }
        #notice {
            color: red;
        }
    </style>
</head>
<body>
<h1>极验验证SDKDemo</h1>
<form class="popup" action="validate" method="post">
    <h2>嵌入式Demo，使用表单形式提交二次验证所需的验证结果值</h2>
    <br>
    <p>
        <label for="username2">用户名：</label>
        <input class="inp" id="username2" type="text" value="极验验证">
    </p>
    <br>
    <p>
        <label for="password2">密&nbsp;&nbsp;&nbsp;&nbsp;码：</label>
        <input class="inp" id="password2" type="password" value="123456">
    </p>

    <div id="embed-captcha"></div>
    <p id="wait" class="show">正在加载验证码......</p>
    <p id="notice" class="hide">请先完成验证</p>

    <br>
    <input class="btn" id="embed-submit" type="submit" value="提交">
</form>
<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js"></script>
<script src="/static/js/gt.js"></script>
<script>
    var handlerEmbed = function (captchaObj) {
        $("#embed-submit").click(function (e) {
            var validate = captchaObj.getValidate();
            if (!validate) {
                $("#notice")[0].className = "show";
                setTimeout(function () {
                    $("#notice")[0].className = "hide";
                }, 2000);
                e.preventDefault();
            }
        });
        // 将验证码加到id为captcha的元素里，同时会有三个input的值：geetest_challenge, geetest_validate, geetest_seccode
        captchaObj.appendTo("#embed-captcha");
        captchaObj.onReady(function () {
            $("#wait")[0].className = "hide";
        });
        // 更多接口参考：http://www.geetest.com/install/sections/idx-client-sdk.html
    };
    $.ajax({
        // 获取id，challenge，success（是否启用failback）
        url: "http://127.0.0.1:8080/test/geet?t=" + (new Date()).getTime(), // 加随机数防止缓存
        type: "get",
        dataType: "json",
        success: function (data) {
            console.log(data);
            // 使用initGeetest接口
            // 参数1：配置参数
            // 参数2：回调，回调的第一个参数验证码对象，之后可以使用它做appendTo之类的事件
            initGeetest({
                gt: data.gt,
                challenge: data.challenge,
                new_captcha: data.new_captcha,
                product: "embed", // 产品形式，包括：float，embed，popup。注意只对PC版验证码有效
                offline: !data.success // 表示用户后台检测极验服务器是否宕机，一般不需要关注
                // 更多配置参数请参见：http://www.geetest.com/install/sections/idx-client-sdk.html#config
            }, handlerEmbed);
        }
    });
</script>
</body>
</html>`

func geetInit(c *gin.Context) {
	response := geetest.GeetestInit(c, "web")

	c.JSON(200, response)
}

func testlogin(c *gin.Context) {
	c.Header("Content-Type", "text/html; charset=utf-8")

	c.String(200, page1)

}

func geetValidate(c *gin.Context) {
	response, _ := geetest.Validate(c, geetest.ClientTypeWEB)
	c.JSON(200, response)

}
